package org.jsola.hr.service.impl;

import org.jsola.core.Page;
import org.jsola.exception.ParamException;
import org.jsola.hr.common.ExampleKit;
import org.jsola.hr.constant.HrConstants;
import org.jsola.hr.dao.IGroupCityDAO;
import org.jsola.hr.dto.GroupCityAddDTO;
import org.jsola.hr.dto.GroupCityUpdateDTO;
import org.jsola.hr.entity.GroupCityDO;
import org.jsola.hr.provider.IPermissionGroupProviderService;
import org.jsola.hr.query.GroupCityQuery;
import org.jsola.hr.service.IGroupCityService;
import org.jsola.hr.vo.GroupCityListVO;
import org.jsola.hr.vo.GroupCityVO;
import org.jsola.permission.entity.GroupDO;
import org.jsola.permission.service.IGroupService;
import org.jsola.user.core.TokenUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 子公司分管城市关系表
 *
 * @author zhr
 */
@Service("hrGroupCityServiceImpl")
public class GroupCityServiceImpl implements IGroupCityService {

    @Autowired
    private IGroupCityDAO groupCityDAO;

    @Autowired
    private IPermissionGroupProviderService groupService;

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public GroupCityVO save(GroupCityAddDTO groupCityAddDTO, TokenUser tokenUser) {
        // 转DO
        GroupCityDO groupCityDO = groupCityAddDTO.to(GroupCityDO.class);
        // 校验组
        checkGroupExis(groupCityDO.getGroupId(), tokenUser.getSiteId());
        // 保存
        groupCityDO = save(groupCityDO, tokenUser.getSiteId(), tokenUser.getUserId());
        return groupCityDO.to(GroupCityVO.class);
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public List<GroupCityVO> batchSave(List<GroupCityAddDTO> groupCityAddDTOList, TokenUser tokenUser) {
        if(CollectionUtils.isEmpty(groupCityAddDTOList)) {
            return null;
        }
        String groupId = groupCityAddDTOList.get(0).getGroupId();
        // 校验组
        checkGroupExis(groupId, tokenUser.getSiteId());
        // 先删除旧的
        deleteByGroup(groupId, tokenUser);

        List<GroupCityDO> groupCityDOList = groupCityAddDTOList
                .parallelStream()
                .map(groupCityAddDTO -> {
                    GroupCityDO groupCityDO = groupCityAddDTO.to(GroupCityDO.class);
                    groupCityDO.preInsert(tokenUser.getUserId());
                    groupCityDO.setSiteId(tokenUser.getSiteId());
                    return groupCityDO;
                }).collect(Collectors.toList());
        groupCityDAO.insertListAndSetId(groupCityDOList);
        return  groupCityDOList
                .parallelStream()
                .map(groupCityDO -> groupCityDO.to(GroupCityVO.class))
                .collect(Collectors.toList());
    }

    @Override
    public GroupCityVO batchSaveAll(String groupId, TokenUser tokenUser) {
        if(StringUtils.isEmpty(groupId)) {
            return null;
        }
        // 校验组
        checkGroupExis(groupId, tokenUser.getSiteId());
        // 先删除旧的
        deleteByGroup(groupId, tokenUser);

        GroupCityAddDTO groupCityAddDTO = new GroupCityAddDTO();
        groupCityAddDTO.setGroupId(groupId);
        groupCityAddDTO.setIsAll(true);
        groupCityAddDTO.setCityCode("");
        groupCityAddDTO.setCityName("");

        return  save(groupCityAddDTO, tokenUser);
    }

    /**
     * 校验组是否存在
     *
     * @param groupId 组id
     * @param siteId  站点
     */
    private void checkGroupExis(String groupId, String siteId) {
        if("0".equals(groupId)){
            return;
        }
        GroupDO groupDO = groupService.selectDOById(groupId, siteId);
        ParamException.notNull(groupDO, "分组不存在或已删除");
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public int update(GroupCityUpdateDTO groupCityUpdateDTO, TokenUser tokenUser) {
        //转DO
        GroupCityDO groupCityDO = groupCityUpdateDTO.to(GroupCityDO.class);
        //根据主键更新，只更新非null值
        return updateByIdSelective(groupCityDO, tokenUser.getSiteId(), tokenUser.getUserId());
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public int deleteByIds(TokenUser tokenUser, String... groupCityIds) {
        return deleteByIds(tokenUser.getSiteId(), tokenUser.getUserId(), (Object[]) groupCityIds);
    }


    @Override
    public GroupCityVO selectById(String groupCityId, String siteId) {
        GroupCityDO groupCityDO = selectDOById(groupCityId, siteId);
        if (groupCityDO == null) {
            return null;
        }
        return groupCityDO.to(GroupCityVO.class);
    }

    @Override
    public List<GroupCityListVO> select(GroupCityQuery groupCityQuery, String siteId) {
        return getVoListByDoList(selectDO(groupCityQuery, siteId));
    }

    /**
     * 根据doList获取voList
     *
     * @param doList doList
     * @return vo
     */
    private List<GroupCityListVO> getVoListByDoList(List<GroupCityDO> doList) {
        if (CollectionUtils.isEmpty(doList)) {
            return doList == null ? null : new ArrayList<>();
        }
        return doList.stream()
                .map(groupCityDO -> groupCityDO.to(GroupCityListVO.class))
                .collect(Collectors.toList());
    }

    @Override
    public int selectCount(GroupCityQuery groupCityQuery, String siteId) {
        Example example = buildExample(groupCityQuery,siteId);
        return groupCityDAO.selectCountByExample(example);
    }

    @Override
    public Page<GroupCityListVO> selectPage(GroupCityQuery groupCityQuery, String siteId) {
        Example example = buildExample(groupCityQuery,siteId);
        Page<GroupCityDO> page = groupCityDAO.selectPageByExample(example,
                groupCityQuery.getPageNo(),
                groupCityQuery.getPageSize());

        return page.to(GroupCityListVO.class);
    }

    @Override
    public GroupCityDO selectDOById(String groupCityId, String siteId) {
        return listById(groupCityId, siteId);
    }

    @Override
    public List<GroupCityDO> selectDO(GroupCityQuery groupCityQuery, String siteId) {
        Example example = buildExample(groupCityQuery,siteId);
        return groupCityDAO.selectByExample(example);
    }

    @Override
    public List<GroupCityListVO> listByGroup(String groupId, String siteId) {
        Example example = new Example(GroupCityDO.class);
        example.and()
                .andEqualTo("groupId", groupId)
                .andEqualTo("siteId", siteId);
        example.orderBy("cityCode");
        return getVoListByDoList(groupCityDAO.selectByExample(example));
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public int deleteByGroup(String groupId, TokenUser tokenUser) {
        List<GroupCityListVO> groupCityList = listByGroup(groupId, tokenUser.getSiteId());
        if (CollectionUtils.isEmpty(groupCityList)) {
            return 0;
        }
        String[] groupCityIds = groupCityList.parallelStream().map(GroupCityListVO::getId).toArray(String[]::new);
        return deleteByIds(tokenUser, groupCityIds);
    }

    @Override
    public List<String> listGroupCityCode(List<String> groupIds, String siteId) {

        Example example = new Example(GroupCityDO.class);
        example.and()
                .andIn("groupId", groupIds)
                .andEqualTo("siteId", siteId);
        example.orderBy("cityCode");

        List<GroupCityDO> groupCityList = groupCityDAO.selectByExample(example);
        if (CollectionUtils.isEmpty(groupCityList)) {
            return null;
        }
        List<GroupCityDO> groupCityDOList = groupCityList.stream()
                .filter(groupCityDO -> groupCityDO.getIsAll() != null && groupCityDO.getIsAll()).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(groupCityDOList)) {
            List<String> list = new ArrayList<>();
            list.add("all");
            return list;
        }
        List<String> cityList = groupCityList.parallelStream().map(GroupCityDO::getCityCode).collect(Collectors.toList());
        return cityList.stream().distinct().collect(Collectors.toList());
    }

    @Override
    public List<String> listByCity(String cityId, String siteId) {
        Example example = new Example(GroupCityDO.class);
        example.and()
                .andEqualTo("cityCode", cityId)
                .andEqualTo("siteId", siteId);

        List<GroupCityDO> groupCityList = groupCityDAO.selectByExample(example);
        if (CollectionUtils.isEmpty(groupCityList)) {
            return null;
        }
        List<String> groupList = groupCityList.parallelStream().map(GroupCityDO::getGroupId).collect(Collectors.toList());
        return groupList.stream().distinct().collect(Collectors.toList());
    }


    /**
     * 根据查询参数，构建example

     * @param groupCityQuery 查询参数
     * @param siteId 所属站点id
     * @return example
     */
    private Example buildExample(GroupCityQuery groupCityQuery, String siteId) {
        Example example = new Example(GroupCityDO.class);
        example.and()
                .andEqualTo("siteId", siteId);
        if (groupCityQuery.getGroupId() != null) {
            example.and().andEqualTo("groupId", groupCityQuery.getGroupId());
        }
        if (groupCityQuery.getCityCode() != null) {
            example.and().andEqualTo("cityCode", groupCityQuery.getCityCode());
        }
        if (groupCityQuery.getCityName() != null) {
            example.and().andEqualTo("cityName", groupCityQuery.getCityName());
        }
        if (groupCityQuery.getProps() != null) {
            example.and().andEqualTo("props", groupCityQuery.getProps());
        }
        if (groupCityQuery.getIsAll() != null) {
            example.and().andEqualTo("isAll", groupCityQuery.getIsAll());
        }
        // 排序
        ExampleKit.setExampleOrder(example,groupCityQuery.getOrders());
        return example;
    }
}




